<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>2.&nbsp;Spring Integration概述</title>
<link rel="stylesheet" href="css/manual.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="index.html"
	title="Spring Integration Reference Manual">
<link rel="up" href="spring-integration-introduction.html"
	title="Part&nbsp;II.&nbsp;Overview of Spring Integration Framework">
<link rel="prev" href="spring-integration-introduction.html"
	title="Part&nbsp;II.&nbsp;Overview of Spring Integration Framework">
<link rel="next" href="spring-integration-core-messaging.html"
	title="Part&nbsp;III.&nbsp;Core Messaging">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084"
	alink="#0000FF">
	<div class="navheader">
		<table width="100%" summary="Navigation header">
			<tr>
				<th colspan="3" align="center">2.&nbsp;Spring Integration概述</th>
			</tr>
			<tr>
				<td width="20%" align="left"><a accesskey="p"
					href="spring-integration-introduction.html">上一页</a>&nbsp;</td>
				<th width="60%" align="center">第二部分：Spring Integration框架概述</th>
				<td width="20%" align="right">&nbsp;<a accesskey="n"
					href="spring-integration-core-messaging.html">下一页</a></td>
			</tr>
		</table>
		<hr>
	</div>
	<div class="chapter" title="2.&nbsp;Spring Integration Overview">
		<div class="titlepage">
			<div>
				<div>
					<h2 class="title">
						<a name="overview"></a>2.&nbsp;Spring Integration概述
					</h2>
				</div>
			</div>
		</div>


		<div class="section" title="2.1&nbsp;Background">
			<div class="titlepage">
				<div>
					<div>
						<h2 class="title" style="clear: both">
							<a name="overview-background"></a>2.1&nbsp;一些背景
						</h2>
					</div>
				</div>
			</div>

			<p>
				Spring框架的一个关键主题是<span
					class="emphasis"><em>控制反转(IoC)</em></span>。广义上，控制反转意味着
				那些由框架上下文管理着的组件由框架来代表履行义务，组件本身自然就无官一身轻了。 比如说，<span
					class="emphasis"><em>依赖注入（DI）</em></span>让组件不需要定位或创建他们的依赖组件。
				相似地，<span class="emphasis"><em>面向方面编程（AOP）</em></span>
				把通用的横向(cross-cutting)处理模块化成为可重用的“方面”，使业务组件无需再关心这些横向
				处理。以上做法，最终的目标都是为了让系统更容易的测试、更容易理解、维护和扩展。
			</p>
			<p>
				不仅如此。Spring框架及其相关工具为开发企业应用提供了一个全面的编程模型。
				这样一个一致的模型让开发人员受益匪浅。尤其需要指出的是，Spring框架本身是构建
				于已经被业界公认、接受的最佳实践上面，比如“面向接口编程”，“组合优于继承”等。
				Spring提供了强大的开发支持库，简化和抽象了一些常用的低层处理，大大提高了程序员
				的工作效率，也提高了系统的可测试性和可移植性。
				</p>
			<p>				
				Spring Integration秉承了Spring框架的这个目标和宗旨。它向消息处理领域扩展了Spring编程模型，
				把Spring本已存在的企业集成支持推进更高的层次，进一步抽象了企业集成支持。
				它支持消息驱动架构（MDA） where inversion of control applies to
				runtime concerns, such as <span class="emphasis"><em>when</em></span>
				certain business logic should execute and <span class="emphasis"><em>where</em></span>
				the response should be sent. 
				它支持消息路径选择和消息变换。通过路径选择和变换，使得不同的传送器及不同的
				数据格式可以集成在一起，又无须牺牲可测试性。
				换言之，消息传递与集成由框架来处理，业务组件进一步从支撑平台中分离出来，
				开发人员进一步摆脱处理复杂的集成问题。
			</p>
			<p>				
				作为Spring编程模型的一个扩展，Spring Integration广泛支持Annotation、
				XML命名空间、通用“bean”的XML支持以及底层API的直接调用。这些API建立在深思熟虑
				过的接口定义，以及非入侵式的代理型适配器上。Spring Integration的设计思路则是
				建立在Spring本身的通用模式与著名的<a class="ulink"
					href="http://www.eaipatterns.com" target="_top">“企业集成模式（EIP）”</a>
				的强强联合之上。“企业集成模式”由同名著作，《企业集成模式》所讲述，作者为Gregor Hohpe
				和Bobby Woolf（Addison Wesley，2004）。看过该书的开发人员应该会觉得Spring Integration
				中的概念和术语非常亲切。
			</p>
		</div>

		<div class="section" title="2.2&nbsp;Goals and Principles">
			<div class="titlepage">
				<div>
					<div>
						<h2 class="title" style="clear: both">
							<a name="overview-goalsandprinciples"></a>2.2&nbsp;Goals and
							Principles
						</h2>
					</div>
				</div>
			</div>

			<p>Spring Integration is motivated by the following goals:</p>
			<div class="itemizedlist">
				<ul class="itemizedlist" type="disc">
					<li class="listitem">
						<p>Provide a simple model for implementing complex enterprise
							integration solutions.</p>
					</li>
					<li class="listitem">
						<p>Facilitate asynchronous, message-driven behavior within a
							Spring-based application.</p>
					</li>
					<li class="listitem">
						<p>Promote intuitive, incremental adoption for existing Spring
							users.</p>
					</li>
				</ul>
			</div>
			<p></p>
			<p>Spring Integration is guided by the following principles:</p>
			<div class="itemizedlist">
				<ul class="itemizedlist" type="disc">
					<li class="listitem">
						<p>
							Components should be <span class="emphasis"><em>loosely
									coupled</em></span> for modularity and testability.
						</p>
					</li>
					<li class="listitem">
						<p>
							The framework should enforce <span class="emphasis"><em>separation
									of concerns</em></span> between business logic and integration logic.
						</p>
					</li>
					<li class="listitem">
						<p>
							Extension points should be abstract in nature but within
							well-defined boundaries to promote <span class="emphasis"><em>reuse</em></span>
							and <span class="emphasis"><em>portability</em></span>.
						</p>
					</li>
				</ul>
			</div>
			<p></p>
		</div>

		<div class="section" title="2.3&nbsp;Main Components">
			<div class="titlepage">
				<div>
					<div>
						<h2 class="title" style="clear: both">
							<a name="overview-components"></a>2.3&nbsp;Main Components
						</h2>
					</div>
				</div>
			</div>

			<p>
				From the <span class="emphasis"><em>vertical</em></span>
				perspective, a layered architecture facilitates separation of
				concerns, and interface-based contracts between layers promote loose
				coupling. Spring-based applications are typically designed this way,
				and the Spring framework and portfolio provide a strong foundation
				for following this best practice for the full-stack of an enterprise
				application. Message-driven architectures add a <span
					class="emphasis"><em>horizontal</em></span> perspective, yet these
				same goals are still relevant. Just as "layered architecture" is an
				extremely generic and abstract paradigm, messaging systems typically
				follow the similarly abstract "pipes-and-filters" model. The
				"filters" represent any component that is capable of producing
				and/or consuming messages, and the "pipes" transport the messages
				between filters so that the components themselves remain
				loosely-coupled. It is important to note that these two high-level
				paradigms are not mutually exclusive. The underlying messaging
				infrastructure that supports the "pipes" should still be
				encapsulated in a layer whose contracts are defined as interfaces.
				Likewise, the "filters" themselves would typically be managed within
				a layer that is logically above the application's service layer,
				interacting with those services through interfaces much in the same
				way that a web-tier would.
			</p>

			<div class="section" title="2.3.1&nbsp;Message">
				<div class="titlepage">
					<div>
						<div>
							<h3 class="title">
								<a name="overview-components-message"></a>2.3.1&nbsp;Message
							</h3>
						</div>
					</div>
				</div>

				<p>In Spring Integration, a Message is a generic wrapper for any
					Java object combined with metadata used by the framework while
					handling that object. It consists of a payload and headers. The
					payload can be of any type and the headers hold commonly required
					information such as id, timestamp, correlation id, and return
					address. Headers are also used for passing values to and from
					connected transports. For example, when creating a Message from a
					received File, the file name may be stored in a header to be
					accessed by downstream components. Likewise, if a Message's content
					is ultimately going to be sent by an outbound Mail adapter, the
					various properties (to, from, cc, subject, etc.) may be configured
					as Message header values by an upstream component. Developers can
					also store any arbitrary key-value pairs in the headers.</p>
				<div class="mediaobject" align="center">
					<img src="images/message.jpg" align="middle">
				</div>
				<p></p>
			</div>

			<div class="section" title="2.3.2&nbsp;Message Channel">
				<div class="titlepage">
					<div>
						<div>
							<h3 class="title">
								<a name="overview-components-channel"></a>2.3.2&nbsp;Message
								Channel
							</h3>
						</div>
					</div>
				</div>

				<p>A Message Channel represents the "pipe" of a
					pipes-and-filters architecture. Producers send Messages to a
					channel, and consumers receive Messages from a channel. The Message
					Channel therefore decouples the messaging components, and also
					provides a convenient point for interception and monitoring of
					Messages.</p>
				<div class="mediaobject" align="center">
					<img src="images/channel.jpg" align="middle">
				</div>
				<p>A Message Channel may follow either Point-to-Point or
					Publish/Subscribe semantics. With a Point-to-Point channel, at most
					one consumer can receive each Message sent to the channel.
					Publish/Subscribe channels, on the other hand, will attempt to
					broadcast each Message to all of its subscribers. Spring
					Integration supports both of these.</p>
				<p>
					Whereas "Point-to-Point" and "Publish/Subscribe" define the two
					options for <span class="emphasis"><em>how many</em></span>
					consumers will ultimately receive each Message, there is another
					important consideration: should the channel buffer messages? In
					Spring Integration, <span class="emphasis"><em>Pollable
							Channels</em></span> are capable of buffering Messages within a queue. The
					advantage of buffering is that it allows for throttling the inbound
					Messages and thereby prevents overloading a consumer. However, as
					the name suggests, this also adds some complexity, since a consumer
					can only receive the Messages from such a channel if a <span
						class="emphasis"><em>poller</em></span> is configured. On the
					other hand, a consumer connected to a <span class="emphasis"><em>Subscribable
							Channel</em></span> is simply Message-driven. The variety of channel
					implementations available in Spring Integration will be discussed
					in detail in <a class="xref"
						href="messaging-channels-section.html#channel-implementations"
						title="3.1.2&nbsp;Message Channel Implementations">Section&nbsp;3.1.2,
						&#8220;Message Channel Implementations&#8221;</a>.
				</p>
			</div>

			<div class="section" title="2.3.3&nbsp;Message Endpoint">
				<div class="titlepage">
					<div>
						<div>
							<h3 class="title">
								<a name="overview-components-endpoint"></a>2.3.3&nbsp;Message
								Endpoint
							</h3>
						</div>
					</div>
				</div>

				<p>
					One of the primary goals of Spring Integration is to simplify the
					development of enterprise integration solutions through <span
						class="emphasis"><em>inversion of control</em></span>. This means
					that you should not have to implement consumers and producers
					directly, and you should not even have to build Messages and invoke
					send or receive operations on a Message Channel. Instead, you
					should be able to focus on your specific domain model with an
					implementation based on plain Objects. Then, by providing
					declarative configuration, you can "connect" your domain-specific
					code to the messaging infrastructure provided by Spring
					Integration. The components responsible for these connections are
					Message Endpoints. This does not mean that you will necessarily
					connect your existing application code directly. Any real-world
					enterprise integration solution will require some amount of code
					focused upon integration concerns such as <span class="emphasis"><em>routing</em></span>
					and <span class="emphasis"><em>transformation</em></span>. The
					important thing is to achieve separation of concerns between such
					integration logic and business logic. In other words, as with the
					Model-View-Controller paradigm for web applications, the goal
					should be to provide a thin but dedicated layer that translates
					inbound requests into service layer invocations, and then
					translates service layer return values into outbound replies. The
					next section will provide an overview of the Message Endpoint types
					that handle these responsibilities, and in upcoming chapters, you
					will see how Spring Integration's declarative configuration options
					provide a non-invasive way to use each of these.
				</p>
			</div>
		</div>

		<div class="section" title="2.4&nbsp;Message Endpoints">
			<div class="titlepage">
				<div>
					<div>
						<h2 class="title" style="clear: both">
							<a name="overview-endpoints"></a>2.4&nbsp;Message Endpoints
						</h2>
					</div>
				</div>
			</div>

			<p>
				A Message Endpoint represents the "filter" of a pipes-and-filters
				architecture. As mentioned above, the endpoint's primary role is to
				connect application code to the messaging framework and to do so in
				a non-invasive manner. In other words, the application code should
				ideally have no awareness of the Message objects or the Message
				Channels. This is similar to the role of a Controller in the MVC
				paradigm. Just as a Controller handles HTTP requests, the Message
				Endpoint handles Messages. Just as Controllers are mapped to URL
				patterns, Message Endpoints are mapped to Message Channels. The goal
				is the same in both cases: isolate application code from the
				infrastructure. These concepts are discussed at length along with
				all of the patterns that follow in the <a class="ulink"
					href="http://www.eaipatterns.com" target="_top">Enterprise
					Integration Patterns</a> book. Here, we provide only a high-level
				description of the main endpoint types supported by Spring
				Integration and their roles. The chapters that follow will elaborate
				and provide sample code as well as configuration examples.
			</p>

			<div class="section" title="2.4.1&nbsp;Transformer">
				<div class="titlepage">
					<div>
						<div>
							<h3 class="title">
								<a name="overview-endpoints-transformer"></a>2.4.1&nbsp;Transformer
							</h3>
						</div>
					</div>
				</div>

				<p>A Message Transformer is responsible for converting a
					Message's content or structure and returning the modified Message.
					Probably the most common type of transformer is one that converts
					the payload of the Message from one format to another (e.g. from
					XML Document to java.lang.String). Similarly, a transformer may be
					used to add, remove, or modify the Message's header values.</p>
			</div>

			<div class="section" title="2.4.2&nbsp;Filter">
				<div class="titlepage">
					<div>
						<div>
							<h3 class="title">
								<a name="overview-endpoints-filter"></a>2.4.2&nbsp;Filter
							</h3>
						</div>
					</div>
				</div>

				<p>A Message Filter determines whether a Message should be
					passed to an output channel at all. This simply requires a boolean
					test method that may check for a particular payload content type, a
					property value, the presence of a header, etc. If the Message is
					accepted, it is sent to the output channel, but if not it will be
					dropped (or for a more severe implementation, an Exception could be
					thrown). Message Filters are often used in conjunction with a
					Publish Subscribe channel, where multiple consumers may receive the
					same Message and use the filter to narrow down the set of Messages
					to be processed based on some criteria.</p>
				<div class="note" title="Note"
					style="margin-left: 0.5in; margin-right: 0.5in;">
					<table border="0" summary="Note">
						<tr>
							<td rowspan="2" align="center" valign="top" width="25"><img
								alt="[Note]" src="images/admon/note.png"></td>
							<th align="left">Note</th>
						</tr>
						<tr>
							<td align="left" valign="top">Be careful not to confuse the
								generic use of "filter" within the Pipes-and-Filters
								architectural pattern with this specific endpoint type that
								selectively narrows down the Messages flowing between two
								channels. The Pipes-and-Filters concept of "filter" matches more
								closely with Spring Integration's Message Endpoint: any
								component that can be connected to Message Channel(s) in order
								to send and/or receive Messages.</td>
						</tr>
					</table>
				</div>
				<p></p>
			</div>

			<div class="section" title="2.4.3&nbsp;Router">
				<div class="titlepage">
					<div>
						<div>
							<h3 class="title">
								<a name="overview-endpoints-router"></a>2.4.3&nbsp;Router
							</h3>
						</div>
					</div>
				</div>

				<p>A Message Router is responsible for deciding what channel or
					channels should receive the Message next (if any). Typically the
					decision is based upon the Message's content and/or metadata
					available in the Message Headers. A Message Router is often used as
					a dynamic alternative to a statically configured output channel on
					a Service Activator or other endpoint capable of sending reply
					Messages. Likewise, a Message Router provides a proactive
					alternative to the reactive Message Filters used by multiple
					subscribers as described above.</p>
				<div class="mediaobject" align="center">
					<img src="images/router.jpg" align="middle">
				</div>
				<p></p>
			</div>

			<div class="section" title="2.4.4&nbsp;Splitter">
				<div class="titlepage">
					<div>
						<div>
							<h3 class="title">
								<a name="overview-endpoints-splitter"></a>2.4.4&nbsp;Splitter
							</h3>
						</div>
					</div>
				</div>

				<p>A Splitter is another type of Message Endpoint whose
					responsibility is to accept a Message from its input channel, split
					that Message into multiple Messages, and then send each of those to
					its output channel. This is typically used for dividing a
					"composite" payload object into a group of Messages containing the
					sub-divided payloads.</p>
			</div>

			<div class="section" title="2.4.5&nbsp;Aggregator">
				<div class="titlepage">
					<div>
						<div>
							<h3 class="title">
								<a name="overview-endpoints-aggregator"></a>2.4.5&nbsp;Aggregator
							</h3>
						</div>
					</div>
				</div>

				<p>
					Basically a mirror-image of the Splitter, the Aggregator is a type
					of Message Endpoint that receives multiple Messages and combines
					them into a single Message. In fact, Aggregators are often
					downstream consumers in a pipeline that includes a Splitter.
					Technically, the Aggregator is more complex than a Splitter,
					because it is required to maintain state (the Messages
					to-be-aggregated), to decide when the complete group of Messages is
					available, and to timeout if necessary. Furthermore, in case of a
					timeout, the Aggregator needs to know whether to send the partial
					results or to discard them to a separate channel. Spring
					Integration provides a
					<code class="interfacename">CompletionStrategy</code>
					as well as configurable settings for timeout, whether to send
					partial results upon timeout, and the discard channel.
				</p>
			</div>

			<div class="section" title="2.4.6&nbsp;Service Activator">
				<div class="titlepage">
					<div>
						<div>
							<h3 class="title">
								<a name="overview-endpoints-service-activator"></a>2.4.6&nbsp;Service
								Activator
							</h3>
						</div>
					</div>
				</div>

				<p>A Service Activator is a generic endpoint for connecting a
					service instance to the messaging system. The input Message Channel
					must be configured, and if the service method to be invoked is
					capable of returning a value, an output Message Channel may also be
					provided.</p>
				<div class="note" title="Note"
					style="margin-left: 0.5in; margin-right: 0.5in;">
					<table border="0" summary="Note">
						<tr>
							<td rowspan="2" align="center" valign="top" width="25"><img
								alt="[Note]" src="images/admon/note.png"></td>
							<th align="left">Note</th>
						</tr>
						<tr>
							<td align="left" valign="top">The output channel is
								optional, since each Message may also provide its own 'Return
								Address' header. This same rule applies for all consumer
								endpoints.</td>
						</tr>
					</table>
				</div>
				<p>The Service Activator invokes an operation on some service
					object to process the request Message, extracting the request
					Message's payload and converting if necessary (if the method does
					not expect a Message-typed parameter). Whenever the service
					object's method returns a value, that return value will likewise be
					converted to a reply Message if necessary (if it's not already a
					Message). That reply Message is sent to the output channel. If no
					output channel has been configured, then the reply will be sent to
					the channel specified in the Message's "return address" if
					available.</p>
				<div class="mediaobject" align="center">
					<img src="images/handler-endpoint.jpg" align="middle">
					<div class="caption">A request-reply "Service Activator"
						endpoint connects a target object's method to input and output
						Message Channels.</div>
				</div>
				<p></p>
			</div>

			<div class="section" title="2.4.7&nbsp;Channel Adapter">
				<div class="titlepage">
					<div>
						<div>
							<h3 class="title">
								<a name="overview-endpoints-channeladapter"></a>2.4.7&nbsp;Channel
								Adapter
							</h3>
						</div>
					</div>
				</div>

				<p>A Channel Adapter is an endpoint that connects a Message
					Channel to some other system or transport. Channel Adapters may be
					either inbound or outbound. Typically, the Channel Adapter will do
					some mapping between the Message and whatever object or resource is
					received-from or sent-to the other system (File, HTTP Request, JMS
					Message, etc). Depending on the transport, the Channel Adapter may
					also populate or extract Message header values. Spring Integration
					provides a number of Channel Adapters, and they will be described
					in upcoming chapters.</p>
				<div class="mediaobject" align="center">
					<img src="images/source-endpoint.jpg" align="middle">
					<div class="caption">An inbound "Channel Adapter" endpoint
						connects a source system to a MessageChannel.</div>
				</div>
				<p></p>
				<div class="mediaobject" align="center">
					<img src="images/target-endpoint.jpg" align="middle">
					<div class="caption">An outbound "Channel Adapter" endpoint
						connects a MessageChannel to a target system.</div>
				</div>
				<p></p>
			</div>
		</div>

	</div>
	<div class="navfooter">
		<hr>
		<table width="100%" summary="Navigation footer">
			<tr>
				<td width="40%" align="left"><a accesskey="p"
					href="spring-integration-introduction.html">Prev</a>&nbsp;</td>
				<td width="20%" align="center"><a accesskey="u"
					href="spring-integration-introduction.html">Up</a></td>
				<td width="40%" align="right">&nbsp;<a accesskey="n"
					href="spring-integration-core-messaging.html">Next</a></td>
			</tr>
			<tr>
				<td width="40%" align="left" valign="top">Part&nbsp;II.&nbsp;Overview
					of Spring Integration Framework&nbsp;</td>
				<td width="20%" align="center"><a accesskey="h"
					href="index.html">Home</a></td>
				<td width="40%" align="right" valign="top">&nbsp;Part&nbsp;III.&nbsp;Core
					Messaging</td>
			</tr>
		</table>
	</div>
	<!-- Begin 2nd Google code - a mod -->
	<script type="text/javascript">
		var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl."
				: "http://www.");
		document
				.write(unescape("%3Cscript src='"
						+ gaJsHost
						+ "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
	</script>
	<script type="text/javascript">
		var OrgTracker = _gat._getTracker("UA-2728886-2");
		OrgTracker._setDomainName("none");
		OrgTracker._setAllowLinker(true);
		OrgTracker._trackPageview();
	</script>
	<!-- End 2nd Google code -->


	<script type="text/javascript">
		function detectLastFrame() {
			var thisF = this.window;
			var allF = parent.top.frames;
			return allF[allF.length - 1] == thisF;
		}

		// Only inject the following code if this is a normal page or the last // frame of a frameset.
		if (parent.top.frames.length == 0 || detectLastFrame()) {
			// Inject the SpringSource search widget too.
			document
					.write(unescape("%3Cscript src='http://search.springsource.org/widget/searchtool.js' type='text/javascript'%3E%3C/script%3E"));
			// Inject the Eloqua code
			document
					.write(unescape("%3Cscript src='/elqNow/elqCfg.js' type='text/javascript'%3E%3C/script%3E"));
			document
					.write(unescape("%3Cscript src='/elqNow/elqImg.js' type='text/javascript'%3E%3C/script%3E"));

		}
	</script>
</body>
</html>